﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;

namespace Cobit5.BIZ.Cobit
{
    public class Process
    {
        #region Model

        private string _id;
        private string _processname;
        private string _processnamechn;
        private string _processdesc;
        private string _processdescchn;
        private string _processpurpose;
        private string _processpurposechn;
        private string _area;
        private string _domain;
        /// <summary>
        /// 
        /// </summary>
        public string Id
        {
            set { _id = value; }
            get { return _id; }
        }
        /// <summary>
        /// 
        /// </summary>
        public string ProcessName
        {
            set { _processname = value; }
            get { return _processname; }
        }
        /// <summary>
        /// 
        /// </summary>
        public string ProcessNameCHN
        {
            set { _processnamechn = value; }
            get { return _processnamechn; }
        }
        /// <summary>
        /// 
        /// </summary>
        public string ProcessDesc
        {
            set { _processdesc = value; }
            get { return _processdesc; }
        }
        /// <summary>
        /// 
        /// </summary>
        public string ProcessDescCHN
        {
            set { _processdescchn = value; }
            get { return _processdescchn; }
        }
        /// <summary>
        /// 
        /// </summary>
        public string ProcessPurpose
        {
            set { _processpurpose = value; }
            get { return _processpurpose; }
        }
        /// <summary>
        /// 
        /// </summary>
        public string ProcessPurposeCHN
        {
            set { _processpurposechn = value; }
            get { return _processpurposechn; }
        }
        /// <summary>
        /// 
        /// </summary>
        public string Area
        {
            set { _area = value; }
            get { return _area; }
        }
        /// <summary>
        /// 
        /// </summary>
        public string Domain
        {
            set { _domain = value; }
            get { return _domain; }
        }

        #endregion Model

        #region ProcessFunction

        /// <summary>
        /// Initialize
        /// </summary>
        public Process(string in_id)
        {
            if (Process.ExistProcess(in_id) == 0)
                return;

            Model.Process myProcess = new Model.Process();
            DAL.Process optProcess = new DAL.Process();
            myProcess = optProcess.GetModel(in_id);

            this._id = myProcess.id;
            this._processname = myProcess.processName;
            this._processnamechn = myProcess.processNameCHN;
            this._processdesc = myProcess.processDesc;
            this._processdescchn = myProcess.processDescCHN;
            this._processpurpose = myProcess.processPurpose;
            this._processpurposechn = myProcess.processPurposeCHN;
            this._area = myProcess.area;
            this._domain = myProcess.domain;
        }

        /// <summary>
        /// Count the number of Process
        /// </summary>
        public static int CountAllProcess()
        {
            DAL.Process optProcess = new DAL.Process();
            return optProcess.GetRecordCount("1=1");
        }

        /// <summary>
        /// List all the Process in pages
        /// </summary>
        public static List<Process> GetAllProcess(string in_orderby, int in_startIndex, int in_endIndex)
        {
            DAL.Process optProcess = new DAL.Process();
            DataSet ds = optProcess.GetListByPage("1=1", in_orderby, in_startIndex, in_endIndex);

            /*** Process not exists ***/
            if (ds == null || ds.Tables[0].Rows.Count < 1)
                return null;

            List<Process> returnListProcess = new List<Process>();
            for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
            {
                Process newProcess = new Process(ds.Tables[0].Rows[i]["id"].ToString());
                returnListProcess.Add(newProcess);
            }

            return returnListProcess;
        }

        /// <summary>
        /// Check if the Process exists
        /// Return  1:Exist;
        ///         0:Not Exist;
        /// </summary>
        public static int ExistProcess(string in_id)
        {
            DAL.Process optProcess = new DAL.Process();
            if (!optProcess.Exists(in_id))
                return 0;
            else return 1;
        }

        /// <summary>
        /// Create a new GoalProcess
        /// Return  1.Success
        ///         2.Id already existed
        ///         3.DAL Error
        /// </summary>
        public static int CreateProcess(string in_id, string in_name, string in_nameCHN, string in_desc, string in_descCHN, string in_purp, string in_purpCHN, string in_area, string in_domain)
        {
            if (Process.ExistProcess(in_id) == 1)
                return 2;

            Model.Process myProcess = new Model.Process();
            myProcess.id = in_id;
            myProcess.processName = in_name;
            myProcess.processNameCHN = in_nameCHN;
            myProcess.processDesc = in_desc;
            myProcess.processDescCHN = in_descCHN;
            myProcess.processPurpose = in_purp;
            myProcess.processPurposeCHN = in_purpCHN;

            DAL.Process optProcess = new DAL.Process();
            bool ok= optProcess.Add(myProcess);
            if (!ok) return 3;
            else return 1;
        }

        /// <summary>
        /// Update the Process
        /// Return: 1.Success
        ///         2.DAL Error
        /// </summary>
        public int UpdateProcess()
        {
            Model.Process myProcess = new Model.Process();
            myProcess.id = this._id;
            myProcess.processName = this._processname;
            myProcess.processNameCHN = this._processnamechn;
            myProcess.processDesc = this._processdesc;
            myProcess.processDescCHN = this._processdescchn;
            myProcess.processPurpose = this._processpurpose;
            myProcess.processPurposeCHN = this._processpurposechn;
            myProcess.area = this._area;
            myProcess.domain = this._domain;

            DAL.Process optProcess = new DAL.Process();
            bool ok = optProcess.Update(myProcess);
            if (!ok) return 2;
            else return 1;
        }

        /// <summary>
        /// Delete one Process
        /// Return: 2.Not Exist Process Id
        ///         3.Error in deleting the relationship with GoalProcess
        ///         4.Error in deleting the relationship with GoalIT
        ///         5.Error in changing the Practice's processID into EMPTY
        ///         1.Success
        /// </summary>
        public static int DeleteProcess(string in_id)
        {
            /*** Check if Process exists ***/
            if (Process.ExistProcess(in_id) == 0)
                return 2;

            /*** Delete all related GoalProcess ***/
            DAL.Process_Goal_Process optPGP = new DAL.Process_Goal_Process();
            DataSet ds = optPGP.GetList("processID='" + in_id + "'");
            if (ds != null )
                if(ds.Tables[0].Rows.Count > 0)
                    for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
                    {
                        bool ok = optPGP.Delete(in_id, int.Parse(ds.Tables[0].Rows[i]["goal_Process"].ToString()));
                        if (!ok) return 3;
                    }

            /*** Delete all related GoalIT ***/
            DAL.Process_Goal_IT optPGI = new DAL.Process_Goal_IT();
            ds = null;
            ds = optPGI.GetList("processID='" + in_id + "'");
            if (ds != null)
                if (ds.Tables[0].Rows.Count > 0)
                    for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
                    {
                        bool ok = optPGI.Delete(in_id, int.Parse(ds.Tables[0].Rows[i]["goal_IT"].ToString()));
                        if (!ok) return 4;
                    }

            /*** Change Practice into Empty ***/
            DAL.Practices optPractice = new DAL.Practices();
            Model.Practices myPractice = new Model.Practices();
            ds = null;
            ds = optPractice.GetList("processID='" + in_id + "'");
            if (ds != null)
                if (ds.Tables[0].Rows.Count > 0)
                    for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
                    {
                        myPractice = null;
                        myPractice = optPractice.GetModel(ds.Tables[0].Rows[i]["id"].ToString());
                        myPractice.processID = "EMPTY";
                        bool ok = optPractice.Update(myPractice);
                        if (!ok) return 5;
                    }
            return 1;
        }

        #endregion ProcessFunctions

        #region Process-GoalProcess

        /// <summary>
        /// Get the number of GoalProcess that belongs to this Process
        /// </summary>
        public int CountGoalProcess()
        {
            DAL.Process_Goal_Process optPGP = new DAL.Process_Goal_Process();
            return optPGP.GetRecordCount("processID='" + this._id + "'");
        }

        /// <summary>
        /// Get the list of GoalProcess
        /// Parameters: 1.in_orderBy:"goal_Process"
        /// </summary>
        public List<GoalProcess> GoalProcesses(string in_orderBy,int in_startIndex,int in_endIndex)
        {
            DAL.Process_Goal_Process optPGP = new DAL.Process_Goal_Process();
            DataSet ds = optPGP.GetListByPage("processID='" + this._id + "'", in_orderBy, in_startIndex, in_endIndex);
            if (ds == null || ds.Tables[0].Rows.Count < 1)
                return null;

            List<GoalProcess> returnListGoalProcess = new List<GoalProcess>();
            for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
            {
                GoalProcess newGoalProcess = new GoalProcess(int.Parse(ds.Tables[0].Rows[i]["goal_Process"].ToString()));
                returnListGoalProcess.Add(newGoalProcess);
            }

            return returnListGoalProcess;
        }

        /// <summary>
        /// Add a GoalProcess to this Process
        /// Parameters: 1.in_id: GoalProcess id
        ///             2.in_priority: p/s
        /// Return: 2.GoalProcess not exists
        ///         3.Error in DAL
        ///         1.Success
        /// </summary>
        public int AddGoalProcess(int in_id,string in_priority)
        {
            if (GoalProcess.ExistGoalProcess(in_id) == 0)
                return 2;

            Model.Process_Goal_Process myPGP = new Model.Process_Goal_Process();
            myPGP.processID = this._id;
            myPGP.goal_Process = in_id;
            myPGP.priority = in_priority;

            DAL.Process_Goal_Process optPGP = new DAL.Process_Goal_Process();
            bool ok = optPGP.Add(myPGP);
            if (!ok) return 3;
            else return 1;
        }

        /// <summary>
        /// Remove a GoalProcess from this Process
        /// Parameters: 1.in_id: GoalProcess id
        /// Return: 2.GoalProcess not exists
        ///         3.Error in DAL
        ///         1.Success
        /// </summary>
        public int RemoveGoalProcess(int in_id)
        {
            if (GoalProcess.ExistGoalProcess(in_id) == 0)
                return 2;

            DAL.Process_Goal_Process optPGP = new DAL.Process_Goal_Process();
            bool ok = optPGP.Delete(this._id, in_id);
            if (!ok) return 3;
            else return 1;
        }

        #endregion Process-GoalProcess

        #region Process-GoalIT

        /// <summary>
        /// Get the number of GoalIT that belongs to this Process
        /// </summary>
        public int CountGoalIT()
        {
            DAL.Process_Goal_IT optPGI = new DAL.Process_Goal_IT();
            return optPGI.GetRecordCount("processID='" + this._id + "'");
        }

        /// <summary>
        /// Get the list of GoalIT
        /// Parameters: 1.in_orderBy:"goal_IT"
        /// </summary>
        public List<GoalIT> GoalITs(string in_orderBy,int in_startIndex,int in_endIndex)
        {
            DAL.Process_Goal_IT optPGI = new DAL.Process_Goal_IT();
            DataSet ds = optPGI.GetListByPage("processID='" + this._id + "'", in_orderBy, in_startIndex, in_endIndex);
            if (ds == null || ds.Tables[0].Rows.Count < 1)
                return null;

            List<GoalIT> returnListGoalIT = new List<GoalIT>();
            for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
            {
                GoalIT newGoalIT = new GoalIT(int.Parse(ds.Tables[0].Rows[i]["goal_IT"].ToString()));
                returnListGoalIT.Add(newGoalIT);
            }

            return returnListGoalIT;
        }

        /// <summary>
        /// Add a GoalIT to this Process
        /// Parameters: 1.in_id: GoalIT id
        ///             2.in_priority: p/s
        /// Return:     2.GoalIT not exists
        ///             3.Error in DAL
        ///             1.Success
        /// </summary>
        public int AddGoalIT(int in_id,string in_priority)
        {
            if (GoalIT.ExistGoalIT(in_id) == 0)
                return 2;

            Model.Process_Goal_IT myPGI = new Model.Process_Goal_IT();
            myPGI.processID = this._id;
            myPGI.goal_IT = in_id;
            myPGI.priority = in_priority;

            DAL.Process_Goal_IT optPGI = new DAL.Process_Goal_IT();
            bool ok = optPGI.Add(myPGI);
            if (!ok) return 3;
            else return 1;
        }

        /// <summary>
        /// Remove a GoalIT from this Process
        /// Parameters: 1.in_id: GoalIT id
        /// Return: 2.GoalIT not exists
        ///         3.Error in DAL
        ///         1.Success
        /// </summary>
        public int RemoveGoalIT(int in_id)
        {
            if (GoalIT.ExistGoalIT(in_id) == 0)
                return 2;

            DAL.Process_Goal_IT optPGI = new DAL.Process_Goal_IT();
            bool ok = optPGI.Delete(this._id, in_id);
            if (!ok) return 3;
            else return 1;
        }

        #endregion Process-GoalIT

        #region Process-Practice

        /// <summary>
        /// Get the number of Practice that belongs to this Process
        /// </summary>
        public int CountPractice()
        {
            DAL.Practices optPractice = new DAL.Practices();
            return optPractice.GetRecordCount("processID='" + this._id + "'");
        }

        /// <summary>
        /// Get the list of Practice
        /// Parameters: 1.in_orderBy:"id","processID","processName"
        /// </summary>
        public List<Practice> Practices(string in_orderBy, int in_startIndex, int in_endIndex)
        {
            DAL.Practices optPractice = new DAL.Practices();
            DataSet ds = optPractice.GetListByPage("processID='" + this._id + "'", in_orderBy, in_startIndex, in_endIndex);
            if (ds == null || ds.Tables[0].Rows.Count < 1)
                return null;

            List<Practice> returnPractice = new List<Practice>();
            for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
            {
                Practice newPractice = new Practice(ds.Tables[0].Rows[i]["id"].ToString());
                returnPractice.Add(newPractice);
            }

            return returnPractice;
        }

        /// <summary>
        /// Add a Practice to this Process
        /// Return: 2.Practice already exists
        ///         3.Error in DAL
        ///         1.Success
        /// </summary>
        public int AddPractice(string in_id, string in_practiceName, string in_practiceNameCHN, string in_practiceDesc, string in_practiceDescCHN, string in_temp)
        {
            return Practice.CreatePractice(in_id, this._id, in_practiceName, in_practiceNameCHN, in_practiceDesc, in_practiceDescCHN, in_temp);
        }

        /// <summary>
        /// Remove a Practice from this Process
        /// Parameters: 1.in_id: Practice id
        /// Return: 2.Practice not exists
        ///         3.Error in DAL
        ///         1.Success
        /// </summary>
        public int RemovePractice(string in_id)
        {
            if (Practice.ExistPractice(in_id) == 0)
                return 2;

            Practice objPractice = new Practice(in_id);
            if (objPractice.processID == "EMPTY")
                return 1;
            else
            {
                objPractice.processID = "EMPTY";
                int ok = objPractice.UpdatePractice();
                if (ok == 2)
                    return 3;
                else
                    return 1;
            }
        }
        
        #endregion Process-Practice
    }
}
